#coding: utf-8

$LOAD_PATH << File.dirname(__FILE__) + "/web-socket-ruby-master/lib"
require "web_socket"

$PORT = 4567
$IS_listeCo = {} #Liste des connectés
$IS_mutexListeCo = Mutex.new #Mutex sur la liste des co

$IS_dependances = {}#Liste des dépendances
$IS_muteDependances = Mutex.new #Mutex sur les dépendances
# Lancement du serveur
TCPServer.open($PORT)
server = WebSocketServer.new(
  :accepted_domains => ["*"],
  :port => $PORT)
puts("Server is running at port %d" % server.port)

# Nouvelle connection
server.run() do |ws|
  user = ""
  begin
    puts("Connection accepted")
    ws.handshake()
    while data = ws.receive()
      tab = data.downcase.split(' ')
      case tab[0]
      when '/id'
        if user.empty?
          user = tab[1].to_s
          $IS_mutexListeCo.synchronize{
            $IS_listeCo[user] = ws
          }
          $IS_muteDependances.synchronize{
            $IS_dependances[user] = []
          }
          puts("User: #{user}")
          ws.send('200')
        end
      when '/dependances'
          calque = tab[1].to_s
          $IS_muteDependances.synchronize{
            $IS_dependances[user] << calque
          }
          puts("Dependances : USER#{user} => CALQUE#{calque}")
          ws.send('210')
      when '/annotation'
          calque = tab[1].to_s
          nb = 0
          $IS_dependances.each_pair{| co , calques|
          if calques.include?(calque) and co != user
             $IS_listeCo[co].send('/UPDATE ' + calque)
             nb+=1
          end 
          }
          puts("Annotation : USER#{user} => CALQUE#{calque}, #{nb} updates") 
          ws.send('220')
      when '/quit'
        $IS_listeCo[user].close
        $IS_mutexListeCo.synchronize{
          $IS_listeCo.delete(user)
        }
        $IS_muteDependances.synchronize{
          $IS_dependances.delete(user)
        }  
        puts("USER #{user} : Connection closed")
      else
        ws.send('000')
      end
    end
  ensure
    $IS_mutexListeCo.synchronize{
      $IS_listeCo.delete(user)
    }
    $IS_muteDependances.synchronize{
      $IS_dependances.delete(user)
    }  
    puts("USER #{user} : Connection closed")
  end
end